C++复习 volatile

  1. volatile[ /ˈvɑː.lə.t̬əl/]
  2. 注意与java等其他语言的volatile作区别

volatile[ /ˈvɑː.lə.t̬əl/]

volatile int i = 10;
  • volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素(操作系统、硬件、其它线程等)更改。所以使用 volatile 告诉编译器不应对这样的对象进行优化。

  • volatile 关键字声明的变量,每次访问时都必须从内存中取出值(没有被 volatile 修饰的变量,可能由于编译器的优化,从 CPU 寄存器中取值)

  • const 可以是 volatile (如只读的状态寄存器)

  • 指针可以是 volatile

    volatile跟const类似可以跟指针,引用等组合

带有volatile的成员函数只能被volatile的对象调用。

  • 合成的拷贝对volatile对象无效

    如果没有定义复制构造函数,编译器会自动合成一个。与合成的默认构造函数不同,即使我们定义了其他构造函数,也会合成复制构造函数。合成复制构造函数会对成员逐个进行初始化,将新对象初始化为原对象的副本。

合成的成员接受的形参类型是常量(非 volatile)引用,以此不能把一个非volatile引用绑定到一个volatile,因此需要自定义。

class Foo
{
public:
    //从一个volatile对象进行拷贝
    Foo(const volatile Foo&);
    //将一个volatile对象赋值给一个*非*Volatile对象
    Foo& operator=(volatile const Foo&);
    //将一个volatile对象赋值给一个volatile对象
    //这个没问题volatile表示这个函数只能被volatile对象调用,而这是个符号重载,所以左值一定是volatile类型
    Foo& operator=(volatile const Foo&) volatile;
    //Foo类的其他部分//
}

注意与java等其他语言的volatile作区别

  • volatile 不能解决多线程中的问题。
  • 按照 Hans Boehm & Nick Maclaren 的总结,volatile 只在三种场合下是合适的。
    • 和信号处理(signal handler)相关的场合;
    • 和内存映射硬件(memory mapped hardware)相关的场合;
    • 和非本地跳转(setjmp 和 longjmp)相关的场合。